using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using mebc.reflection;
using NUnit.Framework;

namespace mebc.tests.metadata
{
    [TestFixture]
    public class test_GetMetaData
    {
        [Test]
        public void Common_metadata()
        {
            var sut = new Part_with_metadata();

            var md = sut.GetMetaData();

            Assert.AreEqual(sut.GetHashCode().ToString(), md.Id);
            Assert.AreEqual(typeof (Part_with_metadata), md.Type);
            Assert.AreEqual("mebc.tests.metadata.Part_with_metadata", md.Name);
            Assert.IsFalse(md.IsBoard);

            var sut2 = new Board_with_metadata();
            md = sut2.GetMetaData();
            Assert.AreEqual(sut2.GetHashCode().ToString(), md.Id);
            Assert.AreEqual(typeof(Board_with_metadata), md.Type);
            Assert.AreEqual("mebc.tests.metadata.Board_with_metadata", md.Name);
            Assert.IsTrue(md.IsBoard);
        }


        [Test]
        public void Input_pins_of_parts_and_boards()
        {
            var sut = new Part_with_metadata();
            var md = sut.GetMetaData();
            Assert.AreEqual(new[]{typeof(int), typeof(string)}, md.InputPins);

            var sut2 = new Board_with_metadata();
            md = sut2.GetMetaData();
            Assert.AreEqual(new[] { typeof(string) }, md.InputPins);
        }


        [Test]
        public void Output_pins_of_boards()
        {
            var sut = new Board_with_metadata();
            var md = sut.GetMetaData();
            Assert.AreEqual(new[] { typeof(int) }, md.OutputPins);
        }

        [Test]
        public void Wires()
        {
            var sut = new Board_with_metadata();

            var md = sut.GetMetaData();

            Assert.AreEqual(3, md.Wires.Count());
            Assert.AreEqual(WireKinds.Input, md.Wires.ElementAt(0).Kind);
            Assert.AreEqual(WireKinds.Output, md.Wires.ElementAt(1).Kind);
            Assert.AreEqual(WireKinds.Flow, md.Wires.ElementAt(2).Kind);
        }
    }


    class Part_with_metadata : Part
    {
        public Part_with_metadata()
        {
            Process<int>(_ => { });
            Process<string>(_ => {});
        }
    }

    class Board_with_metadata : Board
    {
        class A : Part
        {}

        class B : Part
        {}

        public Board_with_metadata()
        {
            var a = new A();
            var b = new B();

            RedirectInputTo<string>(a);
            WireFromTo<StringBuilder>(a, b);
            CaptureOutputFrom<int>(b);
        }
    }
}